// 虚拟列表React组件实现

import React, { useMemo, useCallback, useRef, useEffect } from 'react';
import { useVirtualList } from './useVirtualList';
import { VirtualListProps, VirtualListItemProps, VirtualListMetrics, VIRTUAL_LIST_DEFAULTS } from './types';
import './VirtualList.css';

function VirtualList<T>({
  items,
  containerHeight,
  renderItem,
  itemHeight = VIRTUAL_LIST_DEFAULTS.ITEM_HEIGHT,
  overscan = VIRTUAL_LIST_DEFAULTS.OVERSCAN,
  className = '',
  onScroll,
  onVisibleRangeChange,
  enableVirtualization = VIRTUAL_LIST_DEFAULTS.ENABLE_VIRTUALIZATION,
  scrollThrottleMs = VIRTUAL_LIST_DEFAULTS.SCROLL_THROTTLE_MS
}: VirtualListProps<T>) {
  const metricsRef = useRef<VirtualListMetrics>();
  const lastVisibleRangeRef = useRef<{ start: number; end: number }>({ start: 0, end: 0 });

  // 虚拟列表Hook
  const {
    virtualItems,
    totalSize,
    startIndex,
    endIndex,
    scrollToIndex,
    scrollToOffset,
    containerRef
  } = useVirtualList({
    itemCount: items.length,
    containerHeight,
    itemHeight: typeof itemHeight === 'function' 
      ? (index: number) => itemHeight(index, items[index])
      : itemHeight,
    overscan,
    scrollThrottleMs,
    enableVirtualization
  });

  // 处理滚动事件
  const handleScroll = useCallback((event: React.UIEvent<HTMLDivElement>) => {
    const scrollTop = event.currentTarget.scrollTop;
    onScroll?.(scrollTop);
  }, [onScroll]);

  // 通知可见范围变化
  useEffect(() => {
    const lastRange = lastVisibleRangeRef.current;
    if (startIndex !== lastRange.start || endIndex !== lastRange.end) {
      lastVisibleRangeRef.current = { start: startIndex, end: endIndex };
      onVisibleRangeChange?.(startIndex, endIndex);
    }
  }, [startIndex, endIndex, onVisibleRangeChange]);

  // 计算性能指标
  const metrics = useMemo((): VirtualListMetrics => {
    const isVirtualized = enableVirtualization && items.length >= VIRTUAL_LIST_DEFAULTS.MIN_ITEMS_FOR_VIRTUALIZATION;
    const renderedItems = isVirtualized ? virtualItems.length : items.length;
    const averageItemHeight = virtualItems.length > 0 
      ? virtualItems.reduce((sum, item) => sum + item.size, 0) / virtualItems.length
      : (typeof itemHeight === 'number' ? itemHeight : VIRTUAL_LIST_DEFAULTS.ITEM_HEIGHT);

    return {
      totalItems: items.length,
      renderedItems,
      renderRatio: items.length > 0 ? renderedItems / items.length : 0,
      averageItemHeight,
      scrollPosition: containerRef.current?.scrollTop || 0,
      isVirtualized
    };
  }, [virtualItems, items.length, itemHeight, enableVirtualization, containerRef]);

  // 更新性能指标引用
  useEffect(() => {
    metricsRef.current = metrics;
  }, [metrics]);

  // 渲染项目列表
  const renderedItems = useMemo(() => {
    const isVirtualized = enableVirtualization && items.length >= VIRTUAL_LIST_DEFAULTS.MIN_ITEMS_FOR_VIRTUALIZATION;
    
    if (!isVirtualized) {
      // 非虚拟化模式：渲染所有项目
      return items.map((item, index) => {
        const style: React.CSSProperties = {
          position: 'relative',
          height: typeof itemHeight === 'function' ? itemHeight(index, item) : itemHeight,
          width: '100%'
        };

        return renderItem({
          index,
          item,
          style,
          isVisible: true
        });
      });
    }

    // 虚拟化模式：仅渲染可见项目
    return virtualItems.map((virtualItem) => {
      const { index, start, size } = virtualItem;
      const item = items[index];

      const style: React.CSSProperties = {
        position: 'absolute',
        top: start,
        left: 0,
        height: size,
        width: '100%'
      };

      return renderItem({
        index,
        item,
        style,
        isVisible: index >= startIndex && index <= endIndex
      });
    });
  }, [virtualItems, items, renderItem, itemHeight, enableVirtualization, startIndex, endIndex]);

  // 容器样式
  const containerStyle: React.CSSProperties = {
    height: containerHeight,
    overflow: 'auto',
    position: 'relative'
  };

  // 内容样式
  const contentStyle: React.CSSProperties = {
    height: totalSize,
    position: 'relative',
    width: '100%'
  };

  // 暴露组件实例方法
  const componentRef = useRef<{
    scrollToIndex: typeof scrollToIndex;
    scrollToOffset: typeof scrollToOffset;
    getMetrics: () => VirtualListMetrics | undefined;
  }>();

  useEffect(() => {
    componentRef.current = {
      scrollToIndex,
      scrollToOffset,
      getMetrics: () => metricsRef.current
    };
  });

  return (
    <div
      ref={containerRef}
      className={`virtual-list ${className}`}
      style={containerStyle}
      onScroll={handleScroll}
      data-testid="virtual-list-container"
    >
      <div
        className="virtual-list-content"
        style={contentStyle}
        data-testid="virtual-list-content"
      >
        {renderedItems}
      </div>
    </div>
  );
}

// 高阶组件：为VirtualList添加性能监控
export function withPerformanceMonitoring<T>(WrappedComponent: React.ComponentType<VirtualListProps<T>>) {
  return React.forwardRef<any, VirtualListProps<T>>((props, ref) => {
    const renderStartTime = useRef<number>();
    const renderCount = useRef<number>(0);

    useEffect(() => {
      renderStartTime.current = performance.now();
      renderCount.current++;
    });

    useEffect(() => {
      if (renderStartTime.current) {
        const renderTime = performance.now() - renderStartTime.current;
        console.log(`[VirtualList性能] 第${renderCount.current}次渲染耗时: ${renderTime.toFixed(2)}ms`);
      }
    });

    return <WrappedComponent ref={ref} {...props} />;
  });
}

// 导出带性能监控的组件
export const VirtualListWithMonitoring = withPerformanceMonitoring(VirtualList);

export default VirtualList;